package com.spsa.mensajeria.util;

import java.io.IOException;
import java.util.Hashtable;

import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.ibm.mq.MQC;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.spsa.Parametros;
import com.spsa.persistencia.entidades.EstadoInterfaz;

@Singleton
@TransactionManagement(TransactionManagementType.BEAN)
public class ConexionMQ {

	static final Logger logger = LogManager.getLogger(ConexionMQ.class.getName());

	private MQQueueManager queueManager;
	private MQQueue queue;

	@PostConstruct
	public void inicializar() {
		intentarConectar();
	}

	public boolean estaConectado() {
		if (queueManager != null && queueManager.isOpen() && queueManager.isConnected() && queue != null
				&& queue.isOpen())
			return true;
		else
			return false;
	}

	public void intentarConectar() {
		cerrarConexionesPrevias();
		Hashtable props = new Hashtable();
		props.put(MQC.HOST_NAME_PROPERTY, Parametros.get("ConexionMQ.HOST")); //$NON-NLS-1$
		props.put(MQC.CHANNEL_PROPERTY, Parametros.get("ConexionMQ.CANAL")); //$NON-NLS-1$
		props.put(MQC.PORT_PROPERTY, Integer.parseInt(Parametros.get("ConexionMQ.PUERTO"))); //$NON-NLS-1$

		try {
			queueManager = new MQQueueManager(Parametros.get("ConexionMQ.GESTOR_COLA"), props); //$NON-NLS-1$
			queue = queueManager.accessQueue(Parametros.get("ConexionMQ.COLA"), MQC.MQOO_INPUT_SHARED); //$NON-NLS-1$
			logger.info("Se establecio una conexion al servidor MQ"); //$NON-NLS-1$
		} catch (MQException e) {
			logger.error("No se pudo conectar a la Cola", e); //$NON-NLS-1$
		}
	}

	private void cerrarConexionesPrevias() {
		try {
			if(queue != null)
				queue.close();
			if(queueManager != null)
				queueManager.close();
			
			logger.info("Se cerro las conexiones muertas"); //$NON-NLS-1$
		}
		catch(MQException e) {
			logger.error("No se pudo cerrar las conexiones a la cola", e); //$NON-NLS-1$
		}
	}
	
	public EstadoInterfaz siguienteMensaje() throws MQException, IOException, ClassNotFoundException{
		MQMessage message = new MQMessage();
		MQGetMessageOptions optionsGet = new MQGetMessageOptions();

		EstadoInterfaz estadoInterfaz = null;

		optionsGet.options = MQC.MQGMO_WAIT | MQC.MQGMO_SYNCPOINT;
		optionsGet.waitInterval = MQC.MQWI_UNLIMITED;

		queue.get(message, optionsGet);
		estadoInterfaz = (EstadoInterfaz) message.readObject();
		return estadoInterfaz;
	}

	public void commit() {
		try {
			queueManager.commit();
		} catch (Exception e) {
			logger.error("Error al commitear transaccion en MQ", e); //$NON-NLS-1$
		}
	}

	public void rollBack() {
		try {
			queueManager.backout();
		} catch (Exception e) {
			logger.error("Error al hacer roolback a transaccion en MQ", e); //$NON-NLS-1$
		}
	}

}
